package com.aka.tools.funcTools 
{
	import com.aka.tools.Store;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.utils.Dictionary;
	/**
	 * ...
	 * @author Huhanpeng
	 */
	public class CountToCall
	{
		private static var _timesDic:Dictionary = new Dictionary();
		private static var _settingDic:Dictionary = new Dictionary();
		private static var _argDic:Dictionary = new Dictionary();
		
		private static var _readyFuncs:Vector.<Function> = new Vector.<Function>();
		
		
		/////////////////////////////////////////////////////////////////////
		//接口                                                             //
		/////////////////////////////////////////////////////////////////////
		
		public static function add(func:Function, countTimes:int = 1, arg:Array = null, nextFrame:Boolean = false):void
		{
			if ( _timesDic[func] == null ) 
			{
				_timesDic[func] = countTimes;
			}
			else
			{
				throw new Error( "该函数尚有倒数未完成，如需重置请先删除" );
			}
			
			if ( countTimes < 1 ) 
			{
				throw new Error( "函数计数最小为1，不应为" + countTimes.toString() );
			}
			
			_settingDic[func] = nextFrame;
			
			if ( arg != null ) 
			{
				_argDic[func] = arg;
			}
		}
		
		public static function count(func:Function):void
		{
			if ( _timesDic[func] == null ) 
			{
				throw new Error( "该函数并未在倒数队列中" );
			}
			else if ( _timesDic[func] == 0 ) 
			{
				throw new Error( "该函数倒数已结束" );
			}
			
			
			if ( (_timesDic[func]-=1) == 0 ) 
			{
				if ( _settingDic[func] ) 
				{
					getFuncReady( func );
				}
				else
				{
					call( func );
				}
			}
		}
		
		public static function del( func:Function ):void
		{
			if ( _timesDic[func] != null ) 
			{
				delete _timesDic[func];
				delete _settingDic[func];
				delete _argDic[func];
			}		
		}
		
		public static function nextFrameCall(func:Function, arg:Array = null):void
		{
			if ( arg != null ) 
			{
				_argDic[func] = arg;
			}
			
			getFuncReady( func );
		}
		
		
		/////////////////////////////////////////////////////////////////////
		//内部                                                             //
		/////////////////////////////////////////////////////////////////////
		
		private static function getFuncReady(func:Function):void 
		{
			_readyFuncs.push( func );
			
			Store.stage.addEventListener( Event.ENTER_FRAME, onEnterFrame );
		}
		
		private static function onEnterFrame(e:Event):void 
		{
			(e.currentTarget as EventDispatcher).removeEventListener(Event.ENTER_FRAME, onEnterFrame );
			
			var readyFuncs:Vector.<Function> = _readyFuncs;
			_readyFuncs = new Vector.<Function>();
			
			for (var i:int = 0; i < readyFuncs.length; i++) 
			{
				call( readyFuncs[i] );
			}
			
			
		}
		
		private static function call(func:Function):void 
		{
			var arg:Array = _argDic[func];
			del( func );
			func.apply( null, arg);
		}
	}

}